#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

int bits_n(unsigned long value)
{
	return log10(value)/log10(2) + 1;
}

//from integer to char[] of '1' and '0'
static char *m10_to_m2(unsigned long value, int bit_num)
{
	char *bits = malloc(bit_num+1);

	for(int i = bit_num-1; i >= 0; i--){
		if(value % 2 == 1)
			*(bits + i) = '1';
		else
			*(bits + i) = '0';
		value /= 2;
	}
	
	//string
	bits[bit_num] = '\0';
	return bits;
}

char *uint16_to_m2(uint16_t value)
{
	return m10_to_m2(value, 16);
}

char *char_to_bin(char c)
{
	return m10_to_m2(c, 8);
}

//not a string
char *to_bytes(char *bits)
{
	int bit_num = strlen(bits);
	int byte_num = bit_num/8 + (bit_num % 8 == 0 ? 0 : 1);

	char *bytes = malloc(byte_num);
	
	char c;
	int bit_ind;
	//looping bytes
	for(int i = 0; i < byte_num; i++){
		c = 0;

		//looping bits of single byte
		for(int j = 0; j < 8; j++){
			bit_ind = i*8 + j;
			//not true if last byte's not full
			if(bit_ind < bit_num){
				if(*(bits + bit_ind) == '1')
					c += pow(2.0, 7-j);
				printf("bit = %u\n", *(bits + i*8 + j) == '1' ? 1 : 0);
			}
			else
				break;
		}
		*(bytes + i) = c;
		printf("adding %u\n\n", *(bytes + i));
	}
	return bytes;
}

int main()
{	
	char *n1, *n2;
	n1 = uint16_to_m2(65535);
	n2 = uint16_to_m2(1);

	char bits[33] = "";
	strcat(bits, n1);
	strcat(bits, n2);

	printf("%s\n\n", bits);
	
	char *bytes = to_bytes(bits);
	printf("0x%02x 0x%02x 0x%02x 0x%02x\n", *bytes, *(bytes+1), *(bytes+2), *(bytes+3));


	char bits2[19] = "";
	n1 = uint16_to_m2(257);
	n2 = m10_to_m2(2, 2);
	strcat(bits2, n1);
	strcat(bits2, n2);
	printf("%s\t%s\t%s\n", n1, n2, bits2);
	
	char *bytes2 = to_bytes(bits2);
	printf("0x%02x 0x%02x 0x%02x\n", *bytes2, *(bytes2+1), *(bytes2+2));
	
	
	//useless
	free(n1);
	free(n2);
	free(bytes);
}
